#include <sys/stat.h>
#include "protocol.h"

int main(int argc, char *argv[]) {
    int sockfd;
    unsigned short port;

    if (argc == 1) {
        srand(time(NULL));
        port = rand() % 3000 + 2000;
        printf("ftps: No port specified, using %u.\n", port);
    } else if (argc == 2) {
        port = atoi(argv[1]);
    } else {
        fprintf(stderr, "Usage: ftps [listen-port]\n");
        exit(EXIT_FAILURE);
    }

    /* reuse downloads directory, or make our own if necessary */
    if (chdir("downloads") != 0) {
        printf("ftps: No downloads directory, making one.\n");
        if (mkdir("downloads", S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
            perror("ftps");
            exit(EXIT_FAILURE);
        }
        if (chdir("downloads") != 0) {
            perror("ftps");
            exit(EXIT_FAILURE);
        }
    }

    sockfd = SOCKET(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    if (BIND(sockfd, NULL, port) < 0) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    printf("ftps: waiting for connections...\n");
    while (1) {
        ssize_t amt;
        void *storage = malloc(MAX_FILE_DATA);
        FILE *output;
        transfer_header head;

        amt = RECV(sockfd, &head, sizeof head);
        assert(amt == sizeof head);
        head.size = ntohl(head.size);
        output = fopen(head.name, "wb");
        if (output == NULL) {
            fprintf(stderr, "%s: ", head.name);
            perror("open");
            exit(EXIT_FAILURE);
        }
#ifdef DEBUG
        printf("ftps: Receiving file %s of %u bytes\n", head.name, head.size);
#endif
        do {
            amt = RECV(sockfd, storage, MAX_FILE_DATA < head.size ? MAX_FILE_DATA : head.size);
            if (amt == -1) {
                perror("recvfrom");
            } else {
#ifdef DEBUG
                printf("ftps: Writing %u bytes\n", amt);
#endif
                fwrite(storage, 1, amt, output);
                head.size -= amt;
            }
        } while (amt != 0 && head.size > 0);
        if (fclose(output) != 0) {
            perror("close");
            exit(EXIT_FAILURE);
        }
        free(storage);
    }
    CLOSE(sockfd);
    return EXIT_SUCCESS;
}
